package com.tungse.juc.read_write;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class ReadWriteLockDemo {
    public static void main(String[] args) {
        MyCacheLock myCache = new MyCacheLock();
        for (int i = 0; i < 10; i++) {
            final int temp = i;
            new Thread(()->{
                myCache.put(String.valueOf(temp), temp);
            }, String.valueOf(i)).start();
        }

        for (int i = 0; i < 10; i++) {
            final int temp = i;
            new Thread(()->{
                myCache.get(String.valueOf(temp));
            }, String.valueOf(i)).start();
        }
    }
}

//自定义缓存类
class MyCacheLock {
    //volatile保证多个线程之间的可见性
    private volatile Map<String, Object> cache = new HashMap<>();
    private ReadWriteLock rwLock = new ReentrantReadWriteLock();

    //只能有一个线程在写入数据
    public void put(String key, Object value) {
        rwLock.writeLock().lock();
        try {
            System.out.println(Thread.currentThread().getName() + " 正在写入：" + key);
            cache.put(key, value);
            System.out.println(Thread.currentThread().getName() + " 写入完成");
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            rwLock.writeLock().unlock();
        }

    }

    //读取数据  不限制线程数量
    public Object get(String key) {
        rwLock.readLock().lock();
        Object o;
        try {
            System.out.println(Thread.currentThread().getName() + " 开始读取：" + key);
            o = cache.get(key);
            System.out.println(Thread.currentThread().getName() + " 读取完成");
        } finally {
            rwLock.readLock().unlock();
        }

        return o;

    }
}

//自定义缓存类
class MyCache {
    //volatile保证多个线程之间的可见性
    private volatile Map<String, Object> cache = new HashMap<>();

    //写入数据
    public void put(String key, Object value) {
        System.out.println(Thread.currentThread().getName() + " 正在写入：" + key);
        cache.put(key, value);
        System.out.println(Thread.currentThread().getName() + " 写入完成");
    }

    //读取数据
    public Object get(String key) {
        System.out.println(Thread.currentThread().getName() + " 开始读取：" + key);
        Object o = cache.get(key);
        System.out.println(Thread.currentThread().getName() + " 读取完成");
        return o;

    }
}